"""
交互式截图工具
功能：打开浏览器，使用独立悬浮窗控制截图，支持快捷键F9
"""

import sys
import io
import os

# 设置标准输出编码为UTF-8（Windows兼容性）
# 注意：在 windowed 模式（无控制台）下，sys.stdout 为 None，需要特殊处理
if sys.platform == 'win32':
    if sys.stdout is not None and hasattr(sys.stdout, 'buffer'):
        # 有控制台窗口时，设置 UTF-8 编码
        sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding='utf-8')
    else:
        # 无控制台窗口时（windowed模式），重定向到日志文件（exe所在目录）
        if getattr(sys, 'frozen', False):
            # 打包后的exe环境
            exe_dir = os.path.dirname(sys.executable)
        else:
            # Python脚本环境
            exe_dir = os.path.dirname(os.path.abspath(__file__))
        log_file = os.path.join(exe_dir, 'screenshot_tool.log')
        sys.stdout = open(log_file, 'w', encoding='utf-8')
        sys.stderr = sys.stdout

from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.chrome.options import Options
from selenium.common.exceptions import WebDriverException
from webdriver_manager.chrome import ChromeDriverManager
import undetected_chromedriver as uc
from PIL import Image
from io import BytesIO
from datetime import datetime
import time
import os
import argparse
import threading
import tkinter as tk
from tkinter import ttk
import random

# 尝试导入keyboard库（用于全局快捷键）
try:
    import keyboard
    KEYBOARD_AVAILABLE = True
except ImportError:
    KEYBOARD_AVAILABLE = False
    print("提示：安装 keyboard 库可以使用快捷键功能：pip install keyboard")

# =============== 配置项 ===============

# Webhook 配置
WEBHOOK_URL = "https://www.dachen.vip/api/workflow/hooks/NjhjZTFiNGYzN2EzYTM4OTFhYjA3YWUy"  # 留空，用户可以在这里填写webhook地址

# =============== 工具函数 ===============

def get_executable_dir():
    """
    获取可执行文件所在目录
    - 如果是打包后的exe，返回exe所在目录
    - 如果是Python脚本运行，返回脚本所在目录
    """
    if getattr(sys, 'frozen', False):
        # 打包后的exe环境
        return os.path.dirname(sys.executable)
    else:
        # Python脚本环境
        return os.path.dirname(os.path.abspath(__file__))

def send_webhook(title, user_id, url, screenshot_path):
    """
    发送webhook通知（包含截图文件）
    
    参数:
        title: 网页标题
        user_id: 用户ID
        url: 截图网址
        screenshot_path: 本地截图文件路径
    """
    if not WEBHOOK_URL:
        print("  ⚠ Webhook未配置，跳过发送")
        return
    
    try:
        import requests
        import os
        
        # 检查文件是否存在
        if not os.path.exists(screenshot_path):
            print(f"  ⚠ 截图文件不存在: {screenshot_path}")
            return
        
        print(f"\n[Webhook] 发送通知...")
        print(f"  - 标题: {title}")
        print(f"  - 用户ID: {user_id}")
        print(f"  - URL: {url}")
        print(f"  - 截图: {screenshot_path}")
        
        # 打开本地截图文件并上传
        with open(screenshot_path, 'rb') as screenshot_file:
            # 使用 files 参数上传文件（对应 "附件" 类型）
            files = {
                'screenshot': ('screenshot.png', screenshot_file, 'image/png')
            }
            
            # 使用 data 参数传递其他文本字段
            data = {
                'screenshotCount': '1',  # 文本类型
                'title': title,          # 文本类型
                'userId': user_id,       # 文本类型
                'url': url               # 文本类型
            }
            
            # 发送请求（multipart/form-data 格式）
            response = requests.post(
                WEBHOOK_URL, 
                files=files,      # 附件在这里
                data=data,        # 文本字段在这里
                timeout=30        # 上传文件可能需要更长时间
            )
        
        if response.status_code == 200:
            print(f"  ✓ Webhook发送成功")
            print(f"  ✓ 截图已上传")
            try:
                print(f"  响应: {response.text}")
            except:
                pass
        else:
            print(f"  ⚠ Webhook响应异常: {response.status_code}")
            print(f"  响应内容: {response.text}")
            
    except ImportError:
        print("  ⚠ 需要安装 requests 库才能发送webhook: pip install requests")
    except Exception as e:
        print(f"  ⚠ Webhook发送失败: {e}")
        import traceback
        traceback.print_exc()

# =============== 人类行为模拟工具函数 ===============

def human_delay(min_sec=0.5, max_sec=2.0):
    """
    模拟人类操作的随机延迟
    
    参数:
        min_sec: 最小延迟秒数
        max_sec: 最大延迟秒数
    """
    delay_time = random.uniform(min_sec, max_sec)
    time.sleep(delay_time)

# =====================================================

class ScreenshotController(tk.Toplevel):
    """独立的截图控制器悬浮窗 - 简洁版"""
    def __init__(self, master, driver, on_screenshot_callback):
        super().__init__(master)
        self.driver = driver
        self.on_screenshot_callback = on_screenshot_callback
        self.is_taking_screenshot = False
        
        # 多页面拼接模式状态
        self.multi_page_mode = False
        self.multi_page_images = []  # 存储待拼接的图片
        
        # 用户ID
        self.user_id = ""
        
        # 截图模式切换状态（默认为简单模式）
        self.advanced_mode = False
        
        # 窗口设置
        self.title("截图控制器")
        self.geometry("280x120")  # 缩小初始尺寸
        self.resizable(False, False)
        
        # 置顶显示
        self.attributes('-topmost', True)
        
        # 窗口位置（右上角）
        screen_width = self.winfo_screenwidth()
        x = screen_width - 300
        y = 20
        self.geometry(f"280x120+{x}+{y}")
        
        # 设置样式
        self.configure(bg='#f0f0f0')
        
        # 主容器
        main_frame = tk.Frame(self, bg='#f0f0f0')
        main_frame.pack(expand=True, fill='both', padx=15, pady=15)
        
        # 用户ID输入区域（初始显示）
        self.user_id_section = tk.Frame(main_frame, bg='#f0f0f0')
        self.user_id_section.pack(fill='x')
        
        # 用户ID输入框
        user_id_frame = tk.Frame(self.user_id_section, bg='#f0f0f0')
        user_id_frame.pack(pady=(10, 15), fill='x')
        
        user_id_label = tk.Label(
            user_id_frame,
            text="用户ID:",
            font=('Microsoft YaHei UI', 10),
            bg='#f0f0f0',
            fg='#666666'
        )
        user_id_label.pack(side='left', padx=(0, 8))
        
        self.user_id_entry = tk.Entry(
            user_id_frame,
            font=('Microsoft YaHei UI', 10),
            width=12,
            relief='solid',
            bd=1
        )
        self.user_id_entry.pack(side='left', padx=(0, 8))
        
        # 确认按钮
        self.confirm_btn = tk.Button(
            user_id_frame,
            text="确认",
            font=('Microsoft YaHei UI', 9),
            bg='#4299e1',
            fg='white',
            relief='flat',
            cursor='hand2',
            width=6,
            command=self.confirm_user_id
        )
        self.confirm_btn.pack(side='left')
        
        # 截图功能区域（初始隐藏）
        self.screenshot_section = tk.Frame(main_frame, bg='#f0f0f0')
        
        # 状态标签（仅在多页面模式时显示）
        self.status_label = tk.Label(
            self.screenshot_section,
            text="",
            font=('Microsoft YaHei UI', 8),
            bg='#f0f0f0',
            fg='#666666'
        )
        

  # 截屏按钮（直接截取当前可见区域）
        self.simple_screenshot_btn = tk.Button(
            self.screenshot_section,
            text="📷 截屏",
            command=self.trigger_simple_screenshot,
            font=('Microsoft YaHei UI', 11, 'bold'),
            bg='#38a169',
            fg='white',
            activebackground='#2f855a',
            activeforeground='white',
            relief='flat',
            cursor='hand2',
            padx=15,
            pady=8
        )

        # 截图按钮
        self.screenshot_btn = tk.Button(
            self.screenshot_section,
            text="📸 截取完整页面",
            command=self.trigger_screenshot,
            font=('Microsoft YaHei UI', 11, 'bold'),
            bg='#667eea',
            fg='white',
            activebackground='#5568d3',
            activeforeground='white',
            relief='flat',
            cursor='hand2',
            padx=15,
            pady=8
        )
        
        # 多页面拼接按钮
        self.multi_page_btn = tk.Button(
            self.screenshot_section,
            text="📑 截取多个页面",
            command=self.toggle_multi_page_mode,
            font=('Microsoft YaHei UI', 10),
            bg='#48bb78',
            fg='white',
            activebackground='#38a169',
            activeforeground='white',
            relief='flat',
            cursor='hand2',
            padx=15,
            pady=6
        )
        
        # 模式切换按钮
        self.mode_toggle_btn = tk.Button(
            self.screenshot_section,
            text="⚙️ 更多功能",
            command=self.toggle_screenshot_mode,
            font=('Microsoft YaHei UI', 9),
            bg='#6c757d',
            fg='white',
            activebackground='#5a6268',
            activeforeground='white',
            relief='flat',
            cursor='hand2',
            padx=10,
            pady=4
        )
        
        # 初始化按钮显示状态
        self.update_button_visibility()
        
        # 快捷键提示
        if KEYBOARD_AVAILABLE:
            tip_label = tk.Label(
                self.screenshot_section,
                text="快捷键: F9",
                font=('Microsoft YaHei UI', 8),
                bg='#f0f0f0',
                fg='#999999'
            )
            tip_label.pack(pady=(0, 5))
        
        # 状态标签
        self.status_label = tk.Label(
            self.screenshot_section,
            text="",
            font=('Microsoft YaHei UI', 8),
            bg='#f0f0f0',
            fg='#666666'
        )
        self.status_label.pack()
        
        # 防止关闭窗口，只隐藏
        self.protocol("WM_DELETE_WINDOW", self.hide_window)
        
        # 更新当前页面信息
        self.update_current_page_info()
    
    def update_current_page_info(self):
        """更新状态信息 - 仅在多页面模式时显示"""
        if self.multi_page_mode:
            count = len(self.multi_page_images)
            self.status_label.config(text=f"已截取 {count} 个页面")
            self.status_label.pack(pady=(0, 5))
        else:
            # 单页面模式时隐藏状态标签
            self.status_label.pack_forget()
    
    def confirm_user_id(self):
        """确认用户ID并切换界面"""
        self.user_id = self.user_id_entry.get().strip()
        
        if self.user_id:
            # 有用户ID，切换到截图功能界面
            self.switch_to_screenshot_mode()
        # 如果没有用户ID，不做任何操作（静默处理）
    
    def on_user_id_change(self, event=None):
        """用户ID输入框内容变化时的处理（已移除自动切换逻辑）"""
        pass
    
    def switch_to_screenshot_mode(self):
        """切换到截图功能界面"""
        # 隐藏用户ID输入区域
        self.user_id_section.pack_forget()
        
        # 显示截图功能区域
        self.screenshot_section.pack(fill='both', expand=True)
        
        # 调整窗口大小以适应截图功能（增加高度以容纳两个按钮）
        self.geometry("280x220")
        screen_width = self.winfo_screenwidth()
        x = screen_width - 300
        y = 20
        self.geometry(f"280x220+{x}+{y}")
    
    def switch_to_input_mode(self):
        """切换到用户ID输入界面"""
        # 隐藏截图功能区域
        self.screenshot_section.pack_forget()
        
        # 显示用户ID输入区域
        self.user_id_section.pack(fill='x')
        
        # 调整窗口大小
        self.geometry("280x120")
        screen_width = self.winfo_screenwidth()
        x = screen_width - 300
        y = 20
        self.geometry(f"280x120+{x}+{y}")
    
    def toggle_screenshot_mode(self):
        """切换截图模式（简单模式 vs 高级模式）"""
        self.advanced_mode = not self.advanced_mode
        self.update_button_visibility()
    
    def update_button_visibility(self):
        """更新按钮显示状态"""
        # 清除所有按钮的pack状态
        self.simple_screenshot_btn.pack_forget()
        self.screenshot_btn.pack_forget()
        self.multi_page_btn.pack_forget()
        self.mode_toggle_btn.pack_forget()
        
        if self.advanced_mode:
            # 高级模式：显示完整页面和多页面按钮，隐藏简单截屏按钮
            self.screenshot_btn.pack(pady=(0, 8))
            self.multi_page_btn.pack(pady=(0, 8))
            self.mode_toggle_btn.config(text="📷 简单模式")
            self.mode_toggle_btn.pack(pady=(0, 8))
            # 调整窗口高度以适应更多按钮
            self.geometry("280x220")
            screen_width = self.winfo_screenwidth()
            x = screen_width - 300
            y = 20
            self.geometry(f"280x220+{x}+{y}")
        else:
            # 简单模式：只显示截屏按钮
            self.simple_screenshot_btn.pack(pady=(0, 8))
            self.mode_toggle_btn.config(text="⚙️ 更多功能")
            self.mode_toggle_btn.pack(pady=(0, 8))
            # 调整窗口高度
            self.geometry("280x150")
            screen_width = self.winfo_screenwidth()
            x = screen_width - 300
            y = 20
            self.geometry(f"280x150+{x}+{y}")

    def toggle_multi_page_mode(self):
        """切换多页面拼接模式"""
        if self.multi_page_mode:
            # 结束多页面模式，保存拼接图片
            if len(self.multi_page_images) > 0:
                self.save_stitched_images()
            else:
                self.status_label.config(text="❌ 未截取任何页面", fg='#ff9800')
            
            # 重置状态
            self.multi_page_mode = False
            self.multi_page_images = []
            self.multi_page_btn.config(
                text="📑 截取多个页面",
                bg='#48bb78',
                activebackground='#38a169'
            )
            self.update_current_page_info()
        else:
            # 开启多页面模式
            self.multi_page_mode = True
            self.multi_page_images = []
            self.multi_page_btn.config(
                text="🛑 结束并拼接",
                bg='#f56565',
                activebackground='#e53e3e'
            )
            self.page_info_label.config(text="多页面模式 - 已截取 0 个页面")
            self.status_label.config(text="🎯 多页面模式已启动", fg='#48bb78')
    
    def save_stitched_images(self):
        """保存拼接后的多页面截图"""
        try:
            if len(self.multi_page_images) == 0:
                return
            
            self.status_label.config(text="⏳ 正在拼接图片...", fg='#667eea')
            
            # 计算总高度和最大宽度
            total_height = sum(img.height for img in self.multi_page_images)
            max_width = max(img.width for img in self.multi_page_images)
            
            # 创建新的大图
            stitched_image = Image.new('RGB', (max_width, total_height))
            
            # 垂直拼接所有图片
            current_y = 0
            for img in self.multi_page_images:
                stitched_image.paste(img, (0, current_y))
                current_y += img.height
            
            # 保存到exe所在目录
            timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
            exe_dir = get_executable_dir()
            save_path = os.path.join(exe_dir, f"multi_page_screenshot_{timestamp}.png")
            stitched_image.save(save_path, 'PNG', optimize=True)
            
            file_size = os.path.getsize(save_path) / 1024
            count = len(self.multi_page_images)
            
            print("\n" + "="*60)
            print(f"✅ 多页面拼接成功！共 {count} 个页面")
            print(f"  保存位置: {save_path}")
            print(f"  文件大小: {file_size:.2f} KB")
            print(f"  图片尺寸: {max_width}x{total_height}px")
            
            # ========== 阶段二：多页面截图后的随机滚动 ==========
            try:
                print("\n[自然行为] 模拟查看页面...")
                
                # 获取当前页面总高度
                page_height = self.driver.execute_script("""
                    return Math.max(
                        document.body.scrollHeight,
                        document.documentElement.scrollHeight
                    );
                """)
                
                # 随机滚动到页面的某个位置（20%-80%之间）
                final_scroll_ratio = random.uniform(0.2, 0.8)
                final_scroll_position = int(page_height * final_scroll_ratio)
                print(f"  随机浏览到 {int(final_scroll_ratio * 100)}% 位置...")
                self.driver.execute_script(f"window.scrollTo({{top: {final_scroll_position}, behavior: 'smooth'}});")
                
                # 停留一会儿
                final_stay_time = random.uniform(1, 3)
                time.sleep(final_stay_time)
                print(f"  ✓ 自然行为完成")
            except Exception as scroll_error:
                print(f"  ⚠ 滚动行为跳过: {scroll_error}")
            # ====================================================
            
            print("="*60 + "\n")
            
            # 发送webhook（包含截图文件）
            try:
                current_url = self.driver.current_url
                page_title = self.driver.title
                send_webhook(page_title, self.user_id, current_url, save_path)
            except Exception as webhook_error:
                print(f"  ⚠ Webhook处理异常: {webhook_error}")
            
            self.status_label.config(
                text=f"✅ 已拼接 {count} 个页面并保存",
                fg='#00c853'
            )
            
        except Exception as e:
            print(f"\n❌ 拼接失败: {e}")
            import traceback
            traceback.print_exc()
            self.status_label.config(text="❌ 拼接失败", fg='#ff3b30')
    
    def hide_window(self):
        """隐藏窗口而不是关闭"""
        self.withdraw()
    
    def show_window(self):
        """显示窗口"""
        self.deiconify()
        self.lift()
        self.update_current_page_info()
    
    def trigger_screenshot(self):
        """触发截图 - 直接截取当前激活的标签页"""
        if self.is_taking_screenshot:
            return
        
        self.is_taking_screenshot = True
        self.screenshot_btn.config(text="⏳ 处理中...", state='disabled', bg='#999999')
        self.status_label.config(text="检测中...", fg='#667eea')
        
        # 在新线程中执行截图，避免阻塞UI
        def do_screenshot():
            try:
                # 执行截图（内部会自动检测并显示日志）
                success, page_title, screenshot_image = self.on_screenshot_callback(self.multi_page_mode, self.user_id)
                self.after(0, lambda: self.screenshot_complete(success, page_title, screenshot_image))
            except Exception as e:
                print(f"截图错误: {e}")
                import traceback
                traceback.print_exc()
                self.after(0, lambda: self.screenshot_complete(False, None, None))
        
        threading.Thread(target=do_screenshot, daemon=True).start()
    
    def screenshot_complete(self, success, page_title=None, screenshot_image=None):
        """截图完成回调"""
        self.is_taking_screenshot = False
        self.screenshot_btn.config(text="📸 截取完整页面", state='normal', bg='#667eea')
        
        if success:
            if self.multi_page_mode and screenshot_image:
                # 多页面模式：添加到列表
                self.multi_page_images.append(screenshot_image)
                count = len(self.multi_page_images)
                self.update_current_page_info()
                self.status_label.config(text=f"✅ 已添加第 {count} 个页面", fg='#00c853')
            else:
                # 单页面模式：显示保存成功
                if page_title:
                    # 截取标题前30个字符
                    display_title = page_title[:30] + "..." if len(page_title) > 30 else page_title
                    self.status_label.config(text=f"✅ 已截取: {display_title}", fg='#00c853')
                else:
                    self.status_label.config(text="✅ 截图成功", fg='#00c853')
        else:
            self.status_label.config(text="❌ 截图失败", fg='#ff3b30')
        
        # 5秒后恢复到准备状态（仅在非多页面模式下）
        def reset_status():
            if not self.multi_page_mode:
                self.page_info_label.config(text="准备就绪 - 将截取可见页面")
                self.status_label.config(text="")
        
        self.after(5000, reset_status)
    
    def trigger_simple_screenshot(self):
        """触发简单截屏 - 直接截取当前可见区域，不滚动拼接"""
        if self.is_taking_screenshot:
            return
        
        self.is_taking_screenshot = True
        self.simple_screenshot_btn.config(text="⏳ 处理中...", state='disabled', bg='#999999')
        self.status_label.config(text="截屏中...", fg='#38a169')
        
        # 在新线程中执行截屏，避免阻塞UI
        def do_simple_screenshot():
            try:
                # 执行简单截屏
                success, page_title = self.capture_simple_screenshot()
                self.after(0, lambda: self.simple_screenshot_complete(success, page_title))
            except Exception as e:
                print(f"截屏错误: {e}")
                import traceback
                traceback.print_exc()
                self.after(0, lambda: self.simple_screenshot_complete(False, None))
        
        threading.Thread(target=do_simple_screenshot, daemon=True).start()
    
    def simple_screenshot_complete(self, success, page_title=None):
        """简单截屏完成回调"""
        self.is_taking_screenshot = False
        self.simple_screenshot_btn.config(text="📷 截屏", state='normal', bg='#38a169')
        
        if success:
            if page_title:
                # 截取标题前30个字符
                display_title = page_title[:30] + "..." if len(page_title) > 30 else page_title
                self.status_label.config(text=f"✅ 已截屏: {display_title}", fg='#00c853')
            else:
                self.status_label.config(text="✅ 截屏成功", fg='#00c853')
        else:
            self.status_label.config(text="❌ 截屏失败", fg='#ff3b30')
        
        # 5秒后清空状态
        def reset_status():
            self.status_label.config(text="")
        
        self.after(5000, reset_status)
    
    def capture_simple_screenshot(self):
        """简单截屏 - 直接截取当前可见区域"""
        try:
            print("\n" + "="*60)
            print("📷 开始简单截屏...")
            print("="*60)
            
            # 获取当前激活的标签页
            active_handle = get_active_tab_handle(self.driver)
            self.driver.switch_to.window(active_handle)
            
            # 检查当前页面是否可访问
            try:
                current_url = self.driver.current_url
                if current_url.startswith('chrome://') or current_url.startswith('edge://'):
                    print("  ⚠ 系统页面无法截屏")
                    return False, None
            except:
                print("  ⚠ 无法访问当前页面")
                return False, None
            
            # 获取页面信息
            page_title = self.driver.title
            print(f"\n当前URL: {current_url}")
            print(f"页面标题: {page_title}")
            
            # 直接截取当前可见区域
            print("  正在截取当前可见区域...")
            screenshot = self.driver.get_screenshot_as_png()
            
            # 生成文件名
            timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
            safe_title = "".join(c for c in page_title if c.isalnum() or c in (' ', '-', '_')).rstrip()[:50]
            if not safe_title:
                safe_title = "screenshot"
            
            filename = f"{timestamp}_{safe_title}_简单截屏.png"
            save_path = os.path.join(get_executable_dir(), filename)
            
            # 保存截图
            with open(save_path, 'wb') as f:
                f.write(screenshot)
            
            print(f"✅ 简单截屏已保存: {save_path}")
            
            # 发送webhook（如果配置了）
            if WEBHOOK_URL and self.user_id:
                send_webhook(page_title, self.user_id, current_url, save_path)
            
            return True, page_title
            
        except Exception as e:
            print(f"❌ 简单截屏失败: {e}")
            import traceback
            traceback.print_exc()
            return False, None

def get_active_tab_handle(driver):
    """获取浏览器当前激活的标签页句柄
    
    策略：
    1. 不改变当前标签页，直接检测
    2. 找到 visible 的标签页
    3. 如果都不是 visible（因为控制器抢了焦点），用最后一个标签页
    """
    all_handles = driver.window_handles
    
    print(f"\n  🔍 开始检测激活标签页（共 {len(all_handles)} 个标签页）")
    
    # 如果只有一个标签页，直接返回
    if len(all_handles) == 1:
        print(f"  ✓ 只有1个标签页，直接使用")
        return all_handles[0]
    
    # 保存当前所在的标签页，后面恢复用
    try:
        original_handle = driver.current_window_handle
        original_index = all_handles.index(original_handle)
        print(f"  ℹ 检测前driver在标签页 [{original_index}]")
    except:
        original_handle = all_handles[0]
        original_index = 0
        print(f"  ⚠ 无法获取当前句柄")
    
    active_handle = None
    visible_handles = []
    tab_info = []  # 记录所有标签页的信息
    
    # 策略优化：直接使用最后一个标签页（用户最近打开/操作的）
    # 不再遍历检测 visibility，因为检测过程本身会改变标签页状态
    print(f"\n  💡 智能决策：")
    print(f"     用户最近打开/切换的标签页通常在最后")
    print(f"     直接选择最后一个标签页")
    
    # 先遍历一遍获取所有标签页信息（用于日志显示）
    print(f"\n  📋 标签页列表：")
    for i, handle in enumerate(all_handles):
        try:
            driver.switch_to.window(handle)
            title = driver.title[:40] if driver.title else "无标题"
            url = driver.current_url[:50] if driver.current_url else ""
            
            marker = " ← 将截取此页面" if i == len(all_handles) - 1 else ""
            print(f"  [{i}] {title}")
            print(f"      URL: {url}{marker}")
        except Exception as e:
            print(f"  [{i}] 检测失败: {e}")
            continue
    
    # 决策：使用最后一个标签页
    active_handle = all_handles[-1]
    final_index = len(all_handles) - 1
    
    print(f"\n  🤔 决策过程：")
    print(f"     选择标签页: [{final_index}]（最后一个，即用户最近操作的）")
    
    # 切换到目标标签页
    driver.switch_to.window(active_handle)
    
    try:
        title = driver.title[:50] if driver.title else "空白页"
        print(f"\n  ✅ 最终选择标签页 [{final_index}]: {title}\n")
    except:
        print(f"\n  ✅ 已切换到目标标签页 [{final_index}]\n")
    
    return active_handle

def capture_current_page(driver, save_path=None, return_image=False, user_id=""):
    """截取当前激活标签页的完整长图
    
    参数:
        driver: WebDriver实例
        save_path: 保存路径
        user_id: 用户ID（用于webhook）
        return_image: 是否返回图片对象（多页面模式使用）
    """
    try:
        print("\n" + "="*60)
        print("📸 开始截取当前页面...")
        print("="*60)
        
        # 自动检测并切换到浏览器当前激活的标签页
        print("  正在检测当前激活的标签页...")
        active_handle = get_active_tab_handle(driver)
        driver.switch_to.window(active_handle)
        
        # 检查当前页面是否可访问
        try:
            current_url = driver.current_url
            if current_url.startswith('chrome://') or current_url.startswith('edge://'):
                print("  ⚠ 系统页面无法截图")
                return None
        except:
            print("  ⚠ 无法访问当前页面")
            return None
        
        # 保存用户当前滚动位置
        saved_scroll_position = driver.execute_script("return window.pageYOffset || document.documentElement.scrollTop;")
        
        # 获取页面信息
        page_title = driver.title
        
        print(f"\n当前URL: {current_url}")
        print(f"页面标题: {page_title}")
        
        # 获取页面总高度
        total_height = driver.execute_script("""
            return Math.max(
                document.body.scrollHeight,
                document.body.offsetHeight,
                document.documentElement.clientHeight,
                document.documentElement.scrollHeight,
                document.documentElement.offsetHeight
            );
        """)
        
        # ========== 阶段二：截图前的自然浏览行为 ==========
        print("\n[自然行为] 模拟浏览页面...")
        
        # 步骤1：等待页面加载后的观察期
        observe_time = random.uniform(2, 5)
        print(f"  观察页面 {observe_time:.1f} 秒...")
        time.sleep(observe_time)
        
        # 步骤2：随机向下滚动（模拟浏览内容）
        scroll_ratio = random.uniform(0.2, 0.5)  # 滚动到页面的20%-50%
        browse_scroll_position = int(total_height * scroll_ratio)
        print(f"  向下浏览到 {int(scroll_ratio * 100)}% 位置...")
        driver.execute_script(f"window.scrollTo({{top: {browse_scroll_position}, behavior: 'smooth'}});")
        
        # 等待滚动完成并停留
        time.sleep(random.uniform(1, 2))  # 等待滚动动画
        reading_time = random.uniform(3, 8)
        print(f"  阅读内容 {reading_time:.1f} 秒...")
        time.sleep(reading_time)
        
        # 步骤3：15%概率向上回滚（模拟回看）
        if random.random() < 0.15:
            scroll_back_position = int(browse_scroll_position * random.uniform(0.2, 0.5))
            print(f"  向上回看到 {int(scroll_back_position / total_height * 100)}% 位置...")
            driver.execute_script(f"window.scrollTo({{top: {scroll_back_position}, behavior: 'smooth'}});")
            time.sleep(random.uniform(1, 3))
        
        # 步骤4：重置到顶部，准备开始精确截图
        print(f"  准备截图，返回顶部...")
        driver.execute_script("window.scrollTo(0, 0);")
        human_delay(0.5, 1.0)  # 随机延迟，模拟人类
        print("  ✓ 自然浏览完成，开始精确截图\n")
        # =================================================
        
        # 获取实际截图尺寸
        test_screenshot = driver.get_screenshot_as_png()
        test_image = Image.open(BytesIO(test_screenshot))
        actual_screenshot_width, actual_screenshot_height = test_image.size
        
        # 检测粘性元素（排除悬浮按钮和全屏元素）
        sticky_header_height = driver.execute_script("""
            let maxHeight = 0;
            const viewportHeight = window.innerHeight;
            const elements = document.querySelectorAll('*');
            
            elements.forEach(el => {
                // 排除截图悬浮按钮
                if (el.id === 'screenshot-floating-btn') return;
                
                const style = window.getComputedStyle(el);
                const position = style.position;
                
                if (position === 'fixed' || position === 'sticky') {
                    const rect = el.getBoundingClientRect();
                    
                    // 只考虑顶部的元素（top < 100px）且高度合理
                    // 排除全屏或接近全屏的元素（高度超过视口80%）
                    if (rect.top < 100 && rect.height > 0 && rect.height < viewportHeight * 0.8) {
                        maxHeight = Math.max(maxHeight, rect.bottom);
                    }
                }
            });
            
            return Math.floor(maxHeight);
        """)
        
        print(f"\n页面总高度: {total_height}px")
        print(f"实际截图尺寸: {actual_screenshot_width}x{actual_screenshot_height}px")
        if sticky_header_height > 0:
            print(f"检测到粘性元素: {sticky_header_height}px")
        
        # 开始滚动截图
        print("\n开始滚动截图...")
        stitched_image = Image.new('RGB', (actual_screenshot_width, total_height))
        
        # 计算滚动步长，添加最小值保护
        scroll_step = actual_screenshot_height - sticky_header_height
        min_scroll_step = max(100, int(actual_screenshot_height * 0.2))  # 至少100px或视口的20%
        
        if scroll_step < min_scroll_step:
            print(f"  ⚠ 粘性元素过大({sticky_header_height}px)，使用最小滚动步长: {min_scroll_step}px")
            scroll_step = min_scroll_step
            sticky_header_height = actual_screenshot_height - scroll_step
        
        print(f"  滚动步长: {scroll_step}px")
        
        current_scroll_position = 0
        paste_position = 0
        screenshot_count = 0
        last_paste_position = -1  # 用于检测死循环
        stuck_count = 0  # 连续卡住的次数
        max_screenshots = 200  # 最大截图次数限制（正常情况下不会超过）
        
        while paste_position < total_height and screenshot_count < max_screenshots:
            # 死循环检测
            if paste_position == last_paste_position:
                stuck_count += 1
                if stuck_count > 5:
                    print(f"  ⚠ 检测到死循环，强制终止截图")
                    break
            else:
                stuck_count = 0
                last_paste_position = paste_position
            
            # 滚动到目标位置
            driver.execute_script(f"window.scrollTo(0, {current_scroll_position});")
            human_delay(0.15, 0.35)  # 随机延迟，模拟人类滚动
            
            # 获取实际滚动位置（重要：浏览器可能无法滚动到目标位置）
            actual_scroll_y = driver.execute_script("return window.pageYOffset || document.documentElement.scrollTop;")
            
            # 截图
            screenshot = driver.get_screenshot_as_png()
            screenshot_image = Image.open(BytesIO(screenshot))
            screenshot_count += 1
            
            # 计算裁剪区域（优化后的逻辑）
            if screenshot_count == 1:
                # 第一张截图：完整保留
                crop_top = 0
                crop_height = actual_screenshot_height
            else:
                # 后续截图：需要考虑实际滚动位置和粘性元素
                # 截图内容对应页面范围：[actual_scroll_y, actual_scroll_y + actual_screenshot_height]
                # 期望开始粘贴的位置：paste_position
                
                # 基础裁剪：去掉顶部粘性元素
                crop_top = sticky_header_height
                
                # 检查是否有重叠（当浏览器无法滚动到期望位置时会发生）
                # 例如：页面500px，视口400px，第二次想滚动到400px但实际只能到100px
                if actual_scroll_y < paste_position:
                    # 截图内容的起始位置(actual_scroll_y)早于期望粘贴位置(paste_position)
                    # 说明截图顶部包含了已经粘贴过的内容，需要额外裁剪
                    overlap = paste_position - actual_scroll_y
                    crop_top = overlap + sticky_header_height
                
                # 计算可用高度（截图高度 - 裁剪的顶部）
                crop_height = actual_screenshot_height - crop_top
                
                # 确保不超过剩余需要截取的高度
                remaining_height = total_height - paste_position
                crop_height = min(crop_height, remaining_height)
            
            # 安全检查：确保裁剪参数有效
            if crop_height <= 0:
                print(f"  ⚠ 裁剪高度异常 ({crop_height}px)，停止截图")
                break
            
            # 裁剪图片
            screenshot_image = screenshot_image.crop((
                0, crop_top, actual_screenshot_width, crop_top + crop_height
            ))
            
            # 粘贴到长图
            stitched_image.paste(screenshot_image, (0, paste_position))
            
            # 更新位置
            paste_position += crop_height
            current_scroll_position += scroll_step
            
            # 显示进度
            progress = min(100, int(paste_position / total_height * 100))
            print(f"  进度: {progress}% ({screenshot_count} 张, 滚动: {actual_scroll_y}px)")
            
            # 如果已经完成，提前退出
            if paste_position >= total_height:
                break
        
        # 检查是否正常完成
        if screenshot_count >= max_screenshots:
            print(f"\n  ⚠ 警告：达到最大截图次数限制({max_screenshots}张)，截图可能不完整")
        elif stuck_count > 0:
            print(f"\n  ⚠ 检测到异常，提前终止")
        
        print(f"\n  ✓ 滚动截图完成，共截取 {screenshot_count} 张图片")
        
        # 恢复用户的滚动位置
        driver.execute_script(f"window.scrollTo(0, {saved_scroll_position});")
        time.sleep(0.1)
        
        # 如果是多页面模式，直接返回图片对象
        if return_image:
            print(f"\n✅ 截图完成！（多页面模式，暂不保存）")
            print(f"  图片尺寸: {actual_screenshot_width}x{total_height}px")
            print("="*60 + "\n")
            return (stitched_image, page_title)
        
        # 单页面模式：保存截图到exe所在目录
        if save_path is None:
            timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
            exe_dir = get_executable_dir()
            save_path = os.path.join(exe_dir, f"fullpage_screenshot_{timestamp}.png")
        
        save_dir = os.path.dirname(save_path)
        if save_dir and not os.path.exists(save_dir):
            os.makedirs(save_dir)
        
        stitched_image.save(save_path, 'PNG', optimize=True)
        file_size = os.path.getsize(save_path) / 1024
        
        print(f"\n✅ 截图成功！")
        print(f"  保存位置: {save_path}")
        print(f"  文件大小: {file_size:.2f} KB")
        print(f"  图片尺寸: {actual_screenshot_width}x{total_height}px")
        
        # 发送webhook（单页截图完成，包含截图文件）
        if user_id:
            try:
                send_webhook(page_title, user_id, current_url, save_path)
            except Exception as webhook_error:
                print(f"  ⚠ Webhook处理异常: {webhook_error}")
        
        # ========== 阶段二：截图后的随机滚动 ==========
        print("\n[自然行为] 模拟查看页面...")
        
        # 随机滚动到页面的某个位置（20%-80%之间）
        final_scroll_ratio = random.uniform(0.2, 0.8)
        final_scroll_position = int(total_height * final_scroll_ratio)
        print(f"  随机浏览到 {int(final_scroll_ratio * 100)}% 位置...")
        driver.execute_script(f"window.scrollTo({{top: {final_scroll_position}, behavior: 'smooth'}});")
        
        # 停留一会儿
        final_stay_time = random.uniform(1, 3)
        time.sleep(final_stay_time)
        print(f"  ✓ 自然行为完成")
        # ==============================================
        
        print("="*60 + "\n")
        
        return (save_path, page_title)
        
    except Exception as e:
        print(f"\n❌ 截图失败: {e}")
        import traceback
        traceback.print_exc()
        
        # 恢复滚动位置（如果可能）
        try:
            if 'saved_scroll_position' in locals():
                driver.execute_script(f"window.scrollTo(0, {saved_scroll_position});")
        except:
            pass
        
        return (None, None)

class LoadingWindow:
    """启动提示窗口"""
    def __init__(self):
        self.window = None
        self.should_close = False
    
    def show(self):
        """显示加载窗口"""
        self.window = tk.Tk()
        self.window.title("截图工具")
        self.window.geometry("400x200")
        self.window.resizable(False, False)
        
        # 窗口居中
        screen_width = self.window.winfo_screenwidth()
        screen_height = self.window.winfo_screenheight()
        x = (screen_width - 400) // 2
        y = (screen_height - 200) // 2
        self.window.geometry(f"400x200+{x}+{y}")
        
        # 设置窗口样式
        self.window.configure(bg='#f0f0f0')
        
        # 主容器
        main_frame = tk.Frame(self.window, bg='#f0f0f0')
        main_frame.pack(expand=True, fill='both', padx=20, pady=20)
        
        # 标题
        title_label = tk.Label(
            main_frame, 
            text="🚀 截图工具启动中",
            font=('Microsoft YaHei UI', 16, 'bold'),
            bg='#f0f0f0',
            fg='#333333'
        )
        title_label.pack(pady=(10, 20))
        
        # 提示文本
        info_label = tk.Label(
            main_frame,
            text="正在初始化浏览器，请稍候...\n浏览器窗口即将打开",
            font=('Microsoft YaHei UI', 10),
            bg='#f0f0f0',
            fg='#666666',
            justify='center'
        )
        info_label.pack(pady=10)
        
        # 动画进度条
        style = ttk.Style()
        style.theme_use('clam')
        style.configure("Custom.Horizontal.TProgressbar", 
                       troughcolor='#e0e0e0',
                       background='#667eea',
                       borderwidth=0,
                       thickness=8)
        
        progress = ttk.Progressbar(
            main_frame,
            style="Custom.Horizontal.TProgressbar",
            mode='indeterminate',
            length=300
        )
        progress.pack(pady=20)
        progress.start(10)
        
        # 定期检查是否需要关闭
        def check_close():
            if self.should_close:
                try:
                    self.window.destroy()
                except:
                    pass
            else:
                self.window.after(100, check_close)
        
        self.window.after(100, check_close)
        
        try:
            self.window.mainloop()
        except:
            pass
    
    def close(self):
        """关闭窗口（线程安全）"""
        self.should_close = True
        # 等待一小段时间确保窗口关闭
        time.sleep(0.2)

def interactive_screenshot(start_url=None):
    """交互式截图模式 - 使用独立悬浮窗控制器"""
    driver = None
    loading_window = LoadingWindow()
    root = None
    controller = None
    screenshot_count = [0]  # 使用列表以便在回调中修改
    
    # 在新线程中启动浏览器
    def start_browser():
        nonlocal driver
        try:
            print("="*60)
            print("🌐 交互式截图工具")
            print("="*60)
            
            # 配置Chrome选项
            print("\n[1/3] 配置浏览器...")
            chrome_options = uc.ChromeOptions()
            
            # 使用专用配置目录保存登录状态（exe所在目录）
            exe_dir = get_executable_dir()
            profile_dir = os.path.join(exe_dir, 'chrome_profile')
            chrome_options.add_argument(f'--user-data-dir={profile_dir}')
            chrome_options.add_argument('--profile-directory=ScreenshotProfile')
            
            # 反检测配置
            chrome_options.add_argument('--disable-blink-features=AutomationControlled')
            chrome_options.add_argument('--start-maximized')  # 启动时最大化窗口
            chrome_options.add_argument('--lang=zh-CN')  # 设置语言
            # 注意：undetected_chromedriver会自动处理excludeSwitches和useAutomationExtension
            # 不需要手动设置这些选项
            
            print("  ✓ 浏览器模式：最大化窗口（反检测）")
            print(f"  ✓ 配置目录: {profile_dir}")
            
            # 初始化WebDriver - 使用 undetected-chromedriver
            print("\n[2/3] 启动浏览器（反检测模式）...")
            
            # 尝试多种方式启动浏览器
            driver = None
            startup_methods = [
                # 方法1：尝试自动检测版本（需要网络）
                lambda: uc.Chrome(
                    options=chrome_options,
                    version_main=None,
                    driver_executable_path=None
                ),
                # 方法2：指定常见的Chrome版本（离线模式）
                lambda: uc.Chrome(
                    options=chrome_options,
                    version_main=131,  # Chrome 131
                    driver_executable_path=None
                ),
                lambda: uc.Chrome(
                    options=chrome_options,
                    version_main=130,  # Chrome 130
                    driver_executable_path=None
                ),
                lambda: uc.Chrome(
                    options=chrome_options,
                    version_main=129,  # Chrome 129
                    driver_executable_path=None
                ),
                # 方法3：使用系统默认Chrome（最后的备选方案）
                lambda: uc.Chrome(
                    options=chrome_options,
                    version_main=None,
                    driver_executable_path=None,
                    use_subprocess=False
                )
            ]
            
            for i, method in enumerate(startup_methods, 1):
                try:
                    print(f"  尝试启动方法 {i}/{len(startup_methods)}...")
                    driver = method()
                    print(f"  ✓ 启动成功（方法 {i}）")
                    break
                except Exception as e:
                    print(f"  ✗ 方法 {i} 失败: {str(e)[:100]}...")
                    if i == len(startup_methods):
                        # 所有方法都失败了，抛出最后一个异常
                        raise Exception(f"所有启动方法都失败了。最后一个错误: {e}")
                    continue
            driver.implicitly_wait(10)
            
            # 注入反检测脚本 - 隐藏所有自动化特征
            print("  ✓ 注入反检测脚本...")
            stealth_js = '''
                // 修改 navigator.webdriver (undetected-chromedriver已处理，这里加强)
                Object.defineProperty(navigator, 'webdriver', {
                    get: () => undefined
                });
                
                // 删除所有Selenium注入的变量
                const seleniumVars = [
                    '__webdriver_script_fn', '__driver_evaluate', '__webdriver_evaluate',
                    '__selenium_evaluate', '__fxdriver_evaluate', '__driver_unwrapped',
                    '__webdriver_unwrapped', '__selenium_unwrapped', '__fxdriver_unwrapped',
                    '_Selenium_IDE_Recorder', '_selenium', 'calledSelenium',
                    '_WEBDRIVER_ELEM_CACHE', 'ChromeDriverw', 'driver-evaluate',
                    'webdriver-evaluate', 'selenium-evaluate', 'webdriverCommand'
                ];
                
                seleniumVars.forEach(v => {
                    delete window[v];
                    delete window.document[v];
                });
                
                // 清除document上的特殊属性（Selenium注入的cdc变量）
                Object.keys(document).forEach(key => {
                    if (key.match(/\\$cdc_/) || key.match(/__.*driver/)) {
                        delete document[key];
                    }
                });
                
                // 修复 Chrome 对象
                if (!window.chrome) {
                    window.chrome = {};
                }
                if (!window.chrome.runtime) {
                    window.chrome.runtime = {};
                }
                if (!window.chrome.loadTimes) {
                    window.chrome.loadTimes = function() {};
                }
                if (!window.chrome.csi) {
                    window.chrome.csi = function() {};
                }
                if (!window.chrome.app) {
                    window.chrome.app = {};
                }
                
                // 修复权限API
                const originalQuery = window.navigator.permissions.query;
                window.navigator.permissions.query = (parameters) => (
                    parameters.name === 'notifications' ?
                        Promise.resolve({ state: Notification.permission }) :
                        originalQuery(parameters)
                );
                
                // 修改 plugins
                Object.defineProperty(navigator, 'plugins', {
                    get: () => [
                        {
                            0: {type: "application/x-google-chrome-pdf"},
                            description: "Portable Document Format",
                            filename: "internal-pdf-viewer",
                            length: 1,
                            name: "Chrome PDF Plugin"
                        }
                    ]
                });
            '''
            
            try:
                driver.execute_cdp_cmd('Page.addScriptToEvaluateOnNewDocument', {
                    'source': stealth_js
                })
                print("  ✓ 反检测脚本注入成功")
            except Exception as e:
                print(f"  ⚠ 反检测脚本注入失败: {e}")
            
            # 确保窗口最大化
            try:
                driver.maximize_window()
            except:
                pass
                
            print("  ✓ 浏览器已启动（最大化窗口）")
            
            # 打开起始页面
            if start_url:
                print(f"\n[3/3] 加载页面: {start_url}")
                try:
                    driver.get(start_url)
                    print("  ✓ 页面加载成功")
                except Exception as e:
                    print(f"  ⚠ 页面加载失败: {e}")
                    print("  提示: 尝试打开空白页...")
                    driver.get("about:blank")
            else:
                print(f"\n[3/3] 打开空白页")
                driver.get("about:blank")
            
            # 等待浏览器窗口完全显示（添加随机延迟，模拟人类）
            human_delay(2, 4)
            print("  ✓ 页面准备就绪")
            
            # 关闭加载窗口
            loading_window.close()
            
        except Exception as e:
            print(f"\n❌ 启动失败: {e}")
            loading_window.close()
            raise
    
    def on_screenshot(multi_page_mode=False, user_id=""):
        """截图回调函数 - 截取当前激活的标签页"""
        screenshot_count[0] += 1
        
        if multi_page_mode:
            # 多页面模式：返回图片对象
            print(f"\n📸 开始截图 #{screenshot_count[0]} (多页面模式)")
            result, page_title = capture_current_page(driver, return_image=True, user_id=user_id)
            if result:
                print(f"✅ 第 {screenshot_count[0]} 张截图完成（待拼接）\n")
                return (True, page_title, result)
            else:
                print(f"❌ 第 {screenshot_count[0]} 张截图失败\n")
                return (False, None, None)
        else:
            # 单页面模式：保存文件
            print(f"\n📸 开始截图 #{screenshot_count[0]} (当前激活标签页)")
            save_path, page_title = capture_current_page(driver, user_id=user_id)
            if save_path:
                print(f"✅ 第 {screenshot_count[0]} 张截图已保存\n")
                return (True, page_title, None)
            else:
                print(f"❌ 第 {screenshot_count[0]} 张截图失败\n")
                return (False, None, None)
    
    def check_browser_alive():
        """定期检查浏览器是否还在运行"""
        try:
            window_handles = driver.window_handles
            if not window_handles:
                print("\n🔚 所有浏览器标签页已关闭，程序退出")
                if root:
                    root.quit()
                return
        except:
            print("\n🔚 浏览器已关闭，程序退出")
            if root:
                root.quit()
            return
        
        # 继续定期检查
        if root:
            root.after(1000, check_browser_alive)
    
    def setup_hotkey():
        """设置全局快捷键"""
        if KEYBOARD_AVAILABLE:
            def on_hotkey():
                if controller and not controller.is_taking_screenshot:
                    controller.trigger_screenshot()
            
            try:
                keyboard.add_hotkey('f9', on_hotkey)
                print("  ✓ 快捷键 F9 已注册")
            except Exception as e:
                print(f"  ⚠ 快捷键注册失败: {e}")
    
    try:
        # 在后台线程启动浏览器
        browser_thread = threading.Thread(target=start_browser, daemon=True)
        browser_thread.start()
        
        # 显示加载窗口（会阻塞直到关闭）
        loading_window.show()
        
        # 等待浏览器启动完成
        browser_thread.join()
        
        if driver is None:
            print("\n❌ 浏览器启动失败")
            return
        
        print("\n" + "🎯"*30)
        print("✅ 浏览器已就绪！")
        print("\n使用说明：")
        print("  1. 在浏览器中浏览任何网页、登录账号")
        print("  2. 可以打开多个标签页，自由切换")
        print("  3. 切换到您要截图的标签页")
        print("  4. 点击右上角控制器的【📸 截取当前页面】按钮")
        if KEYBOARD_AVAILABLE:
            print("  5. 或直接按 F9 快捷键截图")
        print("\n💡 新功能 - 多页面拼接：")
        print("  • 点击【📑 截取多个页面】按钮启动拼接模式")
        print("  • 依次截取需要拼接的页面（a、b、c...）")
        print("  • 再次点击按钮【🛑 结束并拼接】完成拼接")
        print("  • 所有页面将垂直拼接成一张长图")
        print("\n📁 文件说明：")
        print("  • 单页面截图保存为：fullpage_screenshot_时间戳.png")
        print("  • 多页面拼接保存为：multi_page_screenshot_时间戳.png")
        print("  • 登录状态会自动保存，下次使用无需重新登录")
        print("  • 关闭所有浏览器标签页即可退出程序")
        print("🎯"*30 + "\n")
        
        # 创建Tkinter根窗口（隐藏）
        root = tk.Tk()
        root.withdraw()  # 隐藏主窗口
        
        # 创建截图控制器悬浮窗
        controller = ScreenshotController(root, driver, on_screenshot)
        controller.show_window()
        
        # 设置快捷键
        setup_hotkey()
        
        # 开始检查浏览器状态
        root.after(1000, check_browser_alive)
        
        # 运行Tkinter主循环
        root.mainloop()
        
        print("\n" + "="*60)
        print(f"✅ 会话结束！共截取 {screenshot_count[0]} 张图片")
        print("="*60)
        
    except Exception as e:
        print(f"\n❌ 错误: {e}")
        import traceback
        traceback.print_exc()
        
    finally:
        # 清理快捷键
        if KEYBOARD_AVAILABLE:
            try:
                keyboard.unhook_all_hotkeys()
            except:
                pass
        
        if driver:
            try:
                driver.quit()
                print("\n✓ 浏览器已关闭，资源已释放")
            except:
                pass

if __name__ == "__main__":
    parser = argparse.ArgumentParser(
        description='交互式截图工具 - 在浏览器中点击按钮截图',
        formatter_class=argparse.RawDescriptionHelpFormatter,
        epilog='''
使用示例:
  # 打开指定网页
  python interactive_screenshot.py --url https://example.com
  
  # 打开空白页（自己输入网址）
  python interactive_screenshot.py
        '''
    )
    
    parser.add_argument('--url', type=str, help='起始页面URL（可选）')
    
    args = parser.parse_args()
    
    # 如果没有指定URL，默认使用Google首页
    default_url = args.url if args.url else "https://www.google.com"
    
    interactive_screenshot(start_url=default_url)
